clear;
%% Erstellen, Trainieren und Testen eines Feedforward Backpropagation Netzwerks

disp('Starting neural network training and test process.');

% Trainings- und Testset erstellen
feature_count = 7; % Anzahl der verwendeten Features
train_count = 350;  % Anzahl der verwendeten Trainingsdatensaetze
[Tr Te] = create_datasets_naive(train_count);    % 100 Datensaetze Training, der rest Test

% Variablen zum Aufnehmen der trainierten Netzwerke initialisieren
trainrounds = 10;
networks = cell(trainrounds,1);

%Ergebnis enthaelt folgende Angaben deren Index zu dem Cell-Array networks
%korrespondiert:
% 1.Spalte: Neuronen in der verborgenen Schicht
% 2.Spalte: Lernrate
% 3.Spalte: Momentum
% 4.Spalte: # richtig klassifizierter Elemente des Testsets
% 5.Spalte: Sum of Squared Error der Testmenge

ergebnis = zeros(trainrounds,5);

test_count = size(Te, 1); % Anzahl der Objekte in der Eingabemenge
dim = size(Te, 2) - 1; % Anzahl der Dimensionen pro Objekt

% Set up Test and Training Data
Tr_Target = transpose(Tr(:, dim+1));
Tr = transpose(Tr(:, 1:dim));

Te_Target = transpose(Te(:, dim+1));
Te = transpose(Te(:, 1:dim));

% Initialisierung und Normalisierung der Parameter
TF = {'tansig' 'tansig'};

% Messen der Trainingszeit
trainAllStart=tic; 
neuron = 7;
lr = 0.7;
mom = 0.6;
for i = 1:trainrounds % Schleife gibt jeder Konfiguration 'trainrounds' Chancen
      networks{i, 1} = neural_train(Tr, Tr_Target, neuron, TF, lr, mom);
      % Parameter Speichern
      ergebnis(i, 1) = neuron;
      ergebnis(i, 2) = lr;
      ergebnis(i, 3) = mom;
end

trainAllElapsed=toc(trainAllStart);

%save ('networks.mat', 'networks');
disp(['Finished network training after ' num2str(trainAllElapsed) ' seconds']);

%% Berechnen welches Netzwerk unser Testset am besten klassifiziert

% Testen mit unseren Testdaten
% Messen der Trainingszeit
testAllStart=tic; 

for i = 1:trainrounds
    % Aufrufen der Klassifikationsfunktion
    [classes error_rate performance] = neural_classify(networks{i,1}, Te, Te_Target);
    % Vergleichen der Klassifikation mit dem Target Vektor
    correct_results = sum(classes == Te_Target) / test_count * 100;
    ergebnis(i, 4) = correct_results; % Klassifikationsrate
    ergebnis(i, 5) = error_rate; % Sum of Squared Errors
end

testAllElapsed=toc(testAllStart);
disp(['Finished network test after ' num2str(testAllElapsed) ' seconds']);

% Gewichte Anzeigen
%network.IW{1,1}
%network.LW{2,1}

%% Post-Training Analyse
allBestClassification = max (ergebnis(:, 4));
allBestSSE = min (ergebnis(:, 5));
mean_cr = mean (ergebnis(:, 4));
std_cr = std (ergebnis(:, 4));
mean_SSE = mean (ergebnis(:, 5));
disp('=== Bestes Result ===');
disp(['Correctly classified: ' num2str(allBestClassification) '%' ]);
disp(['Sum of squared error: ' num2str(allBestSSE) ]);
disp('=== Average Result ===');
disp(['Mean classification rate: ' num2str(mean_cr) ]);
disp(['Mean sum of squared error: ' num2str(std_cr) ]);
disp(['Standard deviation: ' num2str(mean_SSE) ]);
